/*
	   _           _      _           _     _ 
	  (_)         | |    | |         (_)   | |
	   _ _   _ ___| |_ __| |_ __ ___  _  __| |
	  | | | | / __| __/ _` | '__/ _ \| |/ _` |
	  | | |_| \__ \ || (_| | | | (_) | | (_| |
	  | |\__,_|___/\__\__,_|_|  \___/|_|\__,_|
	 _/ |                                     
	|__/ 
	
	Copyright 2013 Caspar Isemer and and Eva Krueger, http://justdroid.org
	
	Licensed under the Apache License, Version 2.0 (the "License");
	you may not use this file except in compliance with the License.
	You may obtain a copy of the License at
	
		http://www.apache.org/licenses/LICENSE-2.0
	
	Unless required by applicable law or agreed to in writing, software
	distributed under the License is distributed on an "AS IS" BASIS,
	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
	See the License for the specific language governing permissions and
	limitations under the License. 
*/

package org.justdroid.justdroid;

import java.util.ArrayList;
import java.util.HashMap;

import android.annotation.SuppressLint;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Vibrator;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.View.OnKeyListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.Toast;

@SuppressLint("DefaultLocale")
public class ContactsApp extends JustDroidActivity {
	private ContactManager contactManager;
	private ArrayList<String> name, number;
	private ListView contactsListView;
	private EditText inputContacts;
	private ContactsAdapter contactsAdapter;
	private Button btnCall, btnSave;
	private ArrayList<String> numberArrayList, contactIdArrayList, idArrayList, nameArrayList;
	private HashMap<String, ArrayList<String>> contactsMap;
	private ProgressBar progressBar;
	private Handler handler;
	private int currentSelection = -1;
	public final int ALL_CONTACTS = 1;
	
	void startNewActivity(int position) {
		//hide the keyboard
		InputMethodManager imm = (InputMethodManager)getApplicationContext().getSystemService(Service.INPUT_METHOD_SERVICE);
		imm.hideSoftInputFromWindow(inputContacts.getWindowToken(), 0);
		//view details
		Intent intent = new Intent(getApplicationContext(), ContactsDetailsMenu.class);
		intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		if(numberArrayList.size() > 0) {
			intent.putExtra("number", numberArrayList.get(position));
			intent.putExtra("name", nameArrayList.get(position));
			intent.putExtra("id", idArrayList.get(position));
		}
		startActivity(intent);
		finish();
	}
	
	void callContact(String inputText) {
		Intent intent = new Intent(getApplicationContext(), PhoneDialerApp.class);
		intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		intent.putExtra("call", inputText);
		startActivity(intent);
		finish();
	}
	
	void saveContact(String inputText) {
		Intent intent = new Intent(getApplicationContext(), SaveContact.class);
		intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		intent.putExtra("number", inputText);
		startActivity(intent);
		finish();
	}
	
	void attachKeyListener(Button button, final int buttonFlag) {
		button.setOnKeyListener(new OnKeyListener() {
			
			@Override
			public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
				if(keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
					switch(keyCode) {
					case KeyEvent.KEYCODE_DPAD_CENTER:
					case KeyEvent.KEYCODE_ENTER:
						switch(buttonFlag) {
							case 1:
								callContact(inputContacts.getText().toString());
								break;
							case 2:
								saveContact(inputContacts.getText().toString());
								break;
						}
						break;
					}
				}
				return false;
			}
		});
	}
	
	/** Create the Contacts activity **/
	@SuppressLint({ "HandlerLeak", "DefaultLocale" })
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		setContentView(R.layout.contacts);
		super.onCreate(savedInstanceState);
		
		/** get the UI elements **/
		contactsListView = (ListView) findViewById(R.id.lstContacts);
		inputContacts = (EditText) findViewById(R.id.inputContactsSearch);
		btnCall = (Button) findViewById(R.id.btnCall);
		btnSave = (Button) findViewById(R.id.btnSave);
		
		contactsListView.setVisibility(View.GONE);
		inputContacts.setEnabled(false);
		
		name = new ArrayList<String>();
		number = new ArrayList<String>();
		contactManager = new ContactManager(getApplicationContext());
		/** display all contacts in the listview **/
		
		//get all contacts and pass to the list adapter
		progressBar = (ProgressBar) findViewById(R.id.progressBar);
		progressBar.setVisibility(View.VISIBLE);
		
		Toast.makeText(getApplicationContext(), getResources().getString(R.string.loadingcontacts), Toast.LENGTH_SHORT).show();
		Runnable runnable = new Runnable() {
			
			@Override
			public void run() {
				if(TTS.isSpeaking())
					TTS.stop();
				if(Utils.isAccessibilityEnabled(getApplicationContext()))
					TTS.speak(getResources().getString(R.string.loadingcontacts));
				ContactsApp.this.contactsMap = contactManager.getAllContacts();
				name = contactsMap.get("name");
				number = contactsMap.get("number");
				idArrayList = contactsMap.get("id");
				numberArrayList = number;
				nameArrayList = name;
				contactIdArrayList = idArrayList;
				Bundle bundle = new Bundle();
				Message message = new Message();
				bundle.putInt("type", ALL_CONTACTS);
				message.setData(bundle);
				handler.sendMessage(message);
			}
		};
		new Thread(runnable).start();		
		
		contactsListView.setOnFocusChangeListener(new OnFocusChangeListener() {
			
			@Override
			public void onFocusChange(View view, boolean hasFocus) {
				if(hasFocus) {
					
				}
			}
		});
		
		//Collections.sort(name);
		//Collections.sort(number);
		//number = contactManager.getAllContacts().get("number");
		contactsListView.setFastScrollEnabled(true);
		contactsListView.setScrollingCacheEnabled(true);
		contactsListView.setItemsCanFocus(true);
		//contactsListView.setTextFilterEnabled(true);
		
		/** handle click events **/
		/*contactsListView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> arg0, View view, int position,
					long arg3) {
				//vibrate
				Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
			    vibrator.vibrate(300);
				TTS.speak(contactsAdapter.getItem(position).toString());
				//hide the keyboard
				InputMethodManager imm = (InputMethodManager)getApplicationContext().getSystemService(Service.INPUT_METHOD_SERVICE);
				imm.hideSoftInputFromWindow(inputContacts.getWindowToken(), 0);
			}
			
		});*/
		
		contactsListView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> arg0, View view, int position,
					long arg3) {
				//hide the keyboard
				InputMethodManager imm = (InputMethodManager)getApplicationContext().getSystemService(Service.INPUT_METHOD_SERVICE);
				imm.hideSoftInputFromWindow(inputContacts.getWindowToken(), 0);
				//view details
				Intent intent = new Intent(getApplicationContext(), ContactsDetailsMenu.class);
				intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
				if(numberArrayList.size() > 0) {
					intent.putExtra("number", numberArrayList.get(position));
					intent.putExtra("name", nameArrayList.get(position));
					intent.putExtra("id", idArrayList.get(position));
				}
				startActivity(intent);
				finish();
			}
			
		});
		
		contactsListView.setOnKeyListener(new OnKeyListener() {			
			@Override
			public boolean onKey(View view, int keyCode, KeyEvent keyEvent) {
				ListView lstView = (ListView) view;
				if(keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
					switch(keyCode) {
					case KeyEvent.KEYCODE_DPAD_CENTER:
					case KeyEvent.KEYCODE_ENTER:
						startNewActivity(currentSelection);
						break;
					case KeyEvent.KEYCODE_DPAD_DOWN:
						currentSelection++;
						if(currentSelection == lstView.getCount()) {
							currentSelection = 0;
						}
						else {
							giveFeedback(contactsListView.getItemAtPosition(currentSelection).toString());
							lstView.setSelection(currentSelection);
						}
						break;
					case KeyEvent.KEYCODE_DPAD_UP:
						currentSelection--;
						if(currentSelection == -1) {
							currentSelection = contactsListView.getCount() - 1;
						}
						else {
							giveFeedback(contactsListView.getItemAtPosition(currentSelection).toString());
							lstView.setSelection(currentSelection);
						}
						break;
					}
				}
				return false;
			}
		});

		inputContacts.addTextChangedListener(new TextWatcher() {

            @SuppressLint("DefaultLocale")
			@Override
            public void onTextChanged(CharSequence cs, int arg1, int arg2,
                    int arg3) {
            	//TTS.speak(TTS.readNumber(cs.toString()));
            	int found = 0;
            	numberArrayList = new ArrayList<String>();
            	nameArrayList = new ArrayList<String>();
            	idArrayList = new ArrayList<String>();
            	//ContactsApp.this.contactsAdapter.getFilter().filter(cs);
            	if(!(inputContacts.getText().toString().matches("-?\\d+(\\.\\d+)?"))) {
	            	for (int i = 0; i < name.size(); i++)
	            	{
		            	if(name.get(i).toString().toLowerCase().
		            			startsWith(inputContacts.getText().toString().toLowerCase()))
		            	{
		            		nameArrayList.add(name.get(i));
		            		numberArrayList.add(number.get(i));
		            		idArrayList.add(contactIdArrayList.get(i));
		            		contactsAdapter = new ContactsAdapter(getApplicationContext(), nameArrayList);
		            		found = 1;
		            	}
	            	}
            	}
            	else { //user entered a number
            		for (int i = 0; i < number.size(); i++)
	            	{
		            	if(number.get(i).toString().startsWith(inputContacts.getText().toString()))
		            	{
		            		nameArrayList.add((new ContactManager(getApplicationContext()).getNameFromNumber(number.get(i))).get("name"));
		            		numberArrayList.add(number.get(i));
		            		idArrayList.add(contactIdArrayList.get(i));
		            		contactsAdapter = new ContactsAdapter(getApplicationContext(), nameArrayList);
		            		found = 1;
		            	}
	            	}
            	}
            	
            	if(found == 1) {
            		btnCall.setVisibility(View.GONE);
            		btnSave.setVisibility(View.GONE);
            		contactsListView.setAdapter(contactsAdapter);
            	}
            	else {
            		//if user typed a NUMBER that is not present in Contacts, display Call and Save buttons
            		if(inputContacts.getText().toString().matches("-?\\d+(\\.\\d+)?")) {
            			btnCall.setVisibility(View.VISIBLE);
            			btnSave.setVisibility(View.VISIBLE);
            			//setonTouchListener
            			/*btnCall.setOnTouchListener(new OnTouchListener() {
							
							@Override
							public boolean onTouch(View arg0, MotionEvent arg1) {
								//vibrate
								Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
							    vibrator.vibrate(200);
							    //TTS feedback
								TTS.speak(btnCall.getText().toString());
								return false;
							}
						});*/
            			
            			//setonFocusChangeListener
            			btnCall.setOnFocusChangeListener(new OnFocusChangeListener() {
							
							@Override
							public void onFocusChange(View arg0, boolean arg1) {
								//vibrate
								Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
							    vibrator.vibrate(200);
							    //TTS feedback
								TTS.speak(btnCall.getText().toString());
							}
						});
            			
            			attachKeyListener(btnCall, 1);
            			
            			//go to PhoneDialerApp on click
            			btnCall.setOnClickListener(new OnClickListener() {
							
							@Override
							public void onClick(View view) {
								callContact(inputContacts.getText().toString());
							}
						});
            			
            			/*//setonTouchListener
            			btnSave.setOnTouchListener(new OnTouchListener() {
							
							@Override
							public boolean onTouch(View arg0, MotionEvent arg1) {
								//vibrate
								Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
							    vibrator.vibrate(200);
							    //TTS feedback
								TTS.speak(btnSave.getText().toString());
								return false;
							}
						});*/
            			
            			//setonFocusChangeListener
            			btnSave.setOnFocusChangeListener(new OnFocusChangeListener() {
							
							@Override
							public void onFocusChange(View arg0, boolean arg1) {
								//vibrate
								Vibrator vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
							    vibrator.vibrate(200);
							    //TTS feedback
								TTS.speak(btnCall.getText().toString());
								finish();
							}
						});
            			
            			attachKeyListener(btnSave, 2);
            			
            			//go to SaveContact on click
            			btnSave.setOnClickListener(new OnClickListener() {
							
							@Override
							public void onClick(View view) {
								saveContact(inputContacts.getText().toString());
							}
						});
            		}
            		else { //user typed letters in the alphabet
            			contactsAdapter = new ContactsAdapter(getApplicationContext(), new ArrayList<String>());
            			btnCall.setVisibility(View.GONE);
                		btnSave.setVisibility(View.GONE);
                		contactsListView.setAdapter(contactsAdapter);
            		}
            	}
            }

            @Override
            public void beforeTextChanged(CharSequence arg0, int arg1,
                    int arg2, int arg3) {

            }

            @Override
            public void afterTextChanged(Editable arg0) {

            }
        });
		
		//TODO: make screen accessible - long click on call and save, vibration on call and save
		
		// Currently, do not know how to write the code that filters contacts while typing,
		// listing matching contacts' first name and last name below each other in ListView
		// then upon clicking on a name open up a contact view that lists all phone numbers
		// on an individual button (UI for that follow up action is at ContactsDetailsMenu.java)
	    
		// START: Remove this once ListView for contacts has been correctly implemented,
		//        as this low tech version with one TextView is only for demo purposes
		/** If Demo Entry is pressed, open the mockup of the Contacts Details Menu **/
		//setTextviewClickAppClass(R.id.txtContactsDemoEntryREMOVE, ContactsApp.this, ContactsDetailsMenu.class);
		// END: Remove this once ListView for contacts has been correctly implemented, as this is only for demo purposes		
		
		handler = new Handler() {
			@Override
			public void handleMessage(Message message) {
				if(message.getData().getInt("type") == ALL_CONTACTS) {
					progressBar.setVisibility(View.GONE);
					//display the contacts in the ListView
					contactsListView.setVisibility(View.VISIBLE);
					contactsAdapter = new ContactsAdapter(getApplicationContext(), name);
					contactsListView.setAdapter(contactsAdapter);
					if(Utils.isAccessibilityEnabled(getApplicationContext()))
						TTS.speak(getResources().getString(R.string.contactsLoaded));
					Toast.makeText(getApplicationContext(), getResources().getString(R.string.contactsLoaded), Toast.LENGTH_SHORT).show();
					inputContacts.setEnabled(true);
				}
			}
		};
		
		/** Put most everything before here **/
	}	
	
	@Override
	public void onResume() {
		super.onResume();
		//if(!TTS.isSpeaking())
			//TTS.speak(getResources().getString(R.string.btnContacts));
		btnCall.setVisibility(View.GONE);
		btnSave.setVisibility(View.GONE);
		inputContacts.setText("");
		contactManager = new ContactManager(getApplicationContext());
		
		//get the root layout
		LinearLayout layout = (LinearLayout) findViewById(R.id.contacts);
		Utils.applyFontColorChanges(getApplicationContext(), layout);  Utils.applyFontSizeChanges(getApplicationContext(), layout);  Utils.applyFontTypeChanges(getApplicationContext(), layout);
	}
}
